#include "QtWidgetsApplication.h"
#include <qlabel.h>
#include <qpushbutton.h>
#include <qimage.h>
#include <qpixmap.h>
#include <qtimer.h>
#include <qslider.h>
#include <QSoundEffect>
#include <QDebug>
#include <QFile>

#include "opencv2/face.hpp"
#include "opencv2/face/facerec.hpp"

using namespace cv;
using namespace std;

QtWidgetsApplication::QtWidgetsApplication(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    qDebug()<<QString::fromLocal8Bit("app start");

    /*
    if(!faceDetector.load("haarcascade_frontalface_alt.xml"))
    {
        qDebug() << "--(!)Error loading";
        return;
    }
*/
    if(!faceDetector.load("haarcascade_frontalface_default.xml"))
    {
        qDebug() << "--(!)Error loading faceDetector";
        return;
    }


    if(!faceDetectorEye.load("haarcascade_eye_tree_eyeglasses.xml"))
    {
        qDebug() << "--(!)Error loading faceDetectorNO";
        return;
    }

/*
    if(!faceDetectorMouth.load("haarcascade_mcs_mouth.xml"))
    {
        qDebug() << "--(!)Error loading faceDetectorNO";
        return;
    }
*/
    //设置显示背景图片
    QSize label_size = ui.label->size();
    //Mat background = Mat::zeros(Size(label_size.width(),label_size.height()) , CV_8UC3);
    //QImage back = QImage((const uchar*)background.data, background.cols, background.rows, QImage::Format::Format_BGR888);
    //QString bgpath= QCoreApplication::applicationDirPath()+"/xoa.png";

    QFile file(":/images/xoa.png");
    file.open(QFile::ReadOnly);
    QByteArray ba = file.readAll();
    Mat logoImage = imdecode(vector<char>(ba.begin(), ba.end()), 1);

    QImage bgimage((const uchar*)logoImage.data, logoImage.cols, logoImage.rows, QImage::Format::Format_BGR888);
    ui.label->setPixmap(QPixmap::fromImage(bgimage.scaled(label_size, Qt::AspectRatioMode::KeepAspectRatio)));

    //设置初始按钮状态
    ui.pushButton2->setDisabled(true);


    //设置摄像头和拍摄定时器
    static VideoCapture capture;
    QTimer* timer = new QTimer;
    timer->setInterval(30);
    connect(timer, &QTimer::timeout, ui.label, [=]() {
        if (!capture.isOpened())
        {
            capture.open(0);
        }

        Mat frame;
        capture.read(frame);

        //QImage qframe((const uchar*)frame.data, frame.cols, frame.rows, QImage::Format::Format_BGR888);
        //ui.label->setPixmap(QPixmap::fromImage(qframe.scaled(label_size, Qt::KeepAspectRatio)));
        //ui.label->setPixmap(QPixmap::fromImage(qframe));

        //人脸检测
        Mat frame_gray;
        cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
        equalizeHist(frame_gray, frame_gray);

        faceDetector.detectMultiScale(frame_gray, faces, 1.2, 3, 0 | CASCADE_SCALE_IMAGE, Size(80 , 80));
        for (int i = 0; i < faces.size(); i++)
        {
          rectangle(frame, faces[i], Scalar(255, 255,255), 2, 8, 0);
        }

        faceDetectorEye.detectMultiScale(frame_gray, facesEye, 1.2, 2, 0 | CASCADE_SCALE_IMAGE, Size(10 ,10));
        for (int i = 0; i < facesEye.size(); i++)
        {
          if(i>1)
             break;
          rectangle(frame, facesEye[i], Scalar(0, 255,0), 2, 8, 0);

        }
/*
        faceDetectorMouth.detectMultiScale(frame_gray, facesMouth, 1.2, 4, 0 | CASCADE_SCALE_IMAGE, Size(40 , 20));
        for (int i = 0; i < facesMouth.size(); i++)
        {
          rectangle(frame, facesMouth[i], Scalar(0, 0,255), 2, 8, 0);
        }
*/

        if(mask_sucess>0)
        {
            //putText(frame, "Mask OK",origin, FONT_HERSHEY_PLAIN, 2.0, Scalar(0,255,0), 2, 8);
            putInfo(frame,"maskok.png");
            mask_sucess--;
        }
        else if(faces.size()>0 ||facesEye.size() >0) //检测到人脸或眼睛
        {
            //有2眼，没有脸，眼睛位置在 画面一半以上，说明戴口罩了
            if(facesEye.size()>1 && faces.size()==0 && facesEye[0].y<300 && facesEye[1].y<300)
            {
                mask_count++;

                if(mask_count>10)
                {
                   //putText(frame, "Mask OK",origin, FONT_HERSHEY_PLAIN, 2.0, Scalar(0,255,0), 2, 8);
                   putInfo(frame,"maskok.png");
                   playsound("maskok.wav");

                   mask_count=0;
                   mask_sucess=40;
                   no_mask_count=0;
                }
                else
                {
                   //putText(frame, "look at the camera please!",origin, FONT_HERSHEY_PLAIN, 2.0, Scalar(255,255,255), 2, 8);
                   putInfo(frame,"look.png");
                   no_mask_count=70;
                }
            }
            else if(facesEye.size()>0 && faces.size()==0) //有1眼，没有脸，说明离得远
            {
                //putText(frame, "look at the camera please!",origin, FONT_HERSHEY_PLAIN, 2.0, Scalar(255,255,255), 2, 8);
                putInfo(frame,"look.png");
                no_mask_count=70;
                if(mask_count>0)
                   mask_count--;
            }
            else
            {
                //putText(frame, "NO Mask!",origin, FONT_HERSHEY_PLAIN, 2.0, Scalar(0, 0,255), 2, 8);


                putInfo(frame,"nomask.png");
                if(no_mask_count==0)
                   playsound("nomask.wav");

                no_mask_count++;
                if(no_mask_count>80)
                   no_mask_count=0;

                mask_count=0;
                mask_sucess=0;
            }

        }
        else
        {
            //putText(frame, "look at the camera please!",origin, FONT_HERSHEY_PLAIN, 2.0, Scalar(255,255,255), 2, 8);
            putInfo(frame,"look.png");
            no_mask_count=70;
            if(mask_count>0)
               mask_count--;
        }

        QImage image((const uchar*)frame.data, frame.cols, frame.rows, QImage::Format::Format_BGR888);
        ui.label->setPixmap(QPixmap::fromImage(image.scaled(label_size, Qt::AspectRatioMode::KeepAspectRatio)));

    });

    //当点击“打开摄像头”按钮
    connect(ui.pushButton1, &QPushButton::clicked, timer, [=]() {
        ui.pushButton1->setDisabled(true);
        ui.pushButton2->setDisabled(false);
        timer->start();
    });

    //当按下“关闭摄像头”按钮
    connect(ui.pushButton2, &QPushButton::clicked, ui.label, [=]() {
        ui.pushButton1->setDisabled(false);
        ui.pushButton2->setDisabled(true);
        if (timer->isActive())
        {
            timer->stop();
        }
        capture.release();
        //Mat background = Mat::zeros(Size(ui.label->width(), ui.label->height()), CV_8UC3);
        //QImage back = QImage((const uchar*)background.data, background.cols, background.rows, QImage::Format::Format_BGR888);
        Mat logoImage = imdecode(vector<char>(ba.begin(), ba.end()), 1);
        QImage bgimage((const uchar*)logoImage.data, logoImage.cols, logoImage.rows, QImage::Format::Format_BGR888);
        ui.label->setPixmap(QPixmap::fromImage(bgimage.scaled(label_size, Qt::AspectRatioMode::KeepAspectRatio)));
    });
}

void putInfo(Mat frame,QString image_name)
{
    QString path= ":/images/"+image_name;

    QFile file(path);
    file.open(QFile::ReadOnly);
    QByteArray ba = file.readAll();
    Mat logoImage = imdecode(vector<char>(ba.begin(), ba.end()), 1);

    if( !logoImage.data ) {  qDebug() << "--(!)Error loading logoImage";}

    // create roi
    Mat imageROI= frame(Rect(50,20,logoImage.cols,logoImage.rows));

    // create mask
    Mat mask= imdecode(vector<char>(ba.begin(), ba.end()), 0);

    logoImage.copyTo(imageROI,mask);
}


void playsound(QString sound_file)
{
     QSoundEffect *m_effect=new QSoundEffect;

     QString dir=QApplication::applicationDirPath();
     QString filename(dir+"/"+sound_file);

     //qDebug() << "playsound "<<filename;

     m_effect->setSource(QUrl::fromLocalFile(filename));

     //设置音量，0-1
     m_effect->setVolume(1.0f);
     m_effect->play();
}
